package com.lingjtx.common.other.http;

import com.alibaba.fastjson2.JSON;
import com.lingjtx.common.core.handle.ObjectPool;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class HttpCall<T> implements Call<T> {

    private final HttpRequest request;
    private final ResponseType responseType;
    private final Type body;
    private final ObjectPool<HttpClient> objectPool;

    public HttpCall(HttpRequest request, ObjectPool<HttpClient> objectPool, ResponseType responseType, Type body) {
        this.request = request;
        this.objectPool = objectPool;
        this.responseType = responseType;
        this.body = body;
    }

    @Override
    public T execute() {
        HttpResponse<String> response = objectPool.execute(httpClient -> {
            try {
                return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (IOException | InterruptedException e) {
                throw new RuntimeException("请求失败！", e);
            }
        });
        return convertResponse(response.body());
    }

    @Override
    public void enqueue(Callback<T> callback) {
        CompletableFuture<HttpResponse<String>> future = objectPool
                .execute(httpClient -> httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()));
        future.thenAccept(response -> {
            T result = convertResponse(response.body());
            callback.onResponse(result);
        }).exceptionally(e -> {
            callback.onFailure(e.getMessage());
            return null;
        });
    }

    // 将响应体转换为目标类型
    private T convertResponse(String responseBody) {
        // 这里可以根据 responseType 进行反序列化
        if (ResponseType.STRING.equals(responseType)) {
            @SuppressWarnings("unchecked") final T body = (T) responseBody;
            return body;
        } else {
            return JSON.parseObject(responseBody, body);
        }
    }
}
